package com.zhouhong;

/**
 * @ClassName: linkedlist
 * @Description: 链表
 * @Author: zhouhong
 * @Create: 2021-03-31 15:25
 **/

public class LinkedList<E> {

    private class Node{
        public E e;
        public Node next;

        public Node(E e, Node next){
            this.e = e;
            this.next = next;
        }
        public Node(E e){
            this(e, null);
        }
        public Node(){
            this(null, null);
        }
        @Override
        public String toString(){
            return e.toString();
        }
    }
    //使用head，会使得add方法在向首部添加元素时找不到当前元素对应的前一个元素
    // private Node head;
    // 虚拟头结点
    private Node dummyHead;
    private int size;

    public LinkedList(){
        dummyHead = new  Node(null, null);
        size = 0;
    }
    // 获取链表中的元素的个数
    public int getSize(){
        return size;
    }
    // 返回链表是否为空
    public boolean isEmpty(){
        return size == 0;
    }
    // 在链表index中间添加元素
    public void add(E e, int index){
        if (index < 0 || index > size){
            throw new IllegalArgumentException("ADD failed, Illegal index.");
        }
        Node pre = dummyHead;
        // 遍历找到所要插入节点的前一个节点
        for (int i = 0; i < index; i++) {
            pre = pre.next;
        }
//          Node node = new Node(e);
//          node.next = pre.next;
//          pre = node;
        pre.next = new Node(e, pre.next);
        size ++;
    }
    // 为链表头部添加元素
    public void addFirst(E e){
//        Node node = new Node(e);
//        node.next = head;
//        head = node;
        add(e,0);
    }
    // 想链表末尾添加元素
    public void addLast(E e){
        add(e, size);
    }
    // 获得链表的第index 个位置的元素
    // 在链表中不是一个常用的操作，练习用
    public E get(int index){
        if (index < 0 || index >= size){
            throw new IllegalArgumentException("ADD failed, Illegal index.");
        }
        Node cur = dummyHead.next;
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        return cur.e;
    }
    // 获得第一个元素
    public E getFirst(){
        return get(0);
    }
    // 获得最后一个元素
    public E getLast(){
        return get(size - 1);
    }
    // 修改链表的第 index 个位置的元素为e
    // 在链表中不是一个常用的操作，练习用
    public void set(int index, E e){
        if (index < 0 || index > size){
            throw new IllegalArgumentException("Update failed, Illegal index.");
        }
        Node cur = dummyHead.next;
        // 遍历找到所要插入节点的前一个节点
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        cur.e = e;
    }
    // 查找链表中是否存在元素e
    public boolean contains(E e){
        Node cur = dummyHead.next;
        while (cur != null){
            if (cur.e.equals(e)){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    // 从链表中删除index位置的元素，返回待删除元素
    public E remove(int index){
        if (index < 0 || index > size){
            throw new IllegalArgumentException("remove failed, Illegal index.");
        }
        Node pre = dummyHead;
        // 遍历找到所要删除节点的前一个节点
        for (int i = 0; i < index; i++) {
            pre = pre.next;
        }
        Node node = pre.next;
        pre.next = node.next;
        node.next = null;
        size --;
        return node.e;
    }
    // 从链表中删除第一个元素,返回删除元素
    public E removeFirst(){
        return remove(0);
    }
    // 从链表中删除最后一个元素,返回删除元素
    public E removeLast(){
        return remove(size - 1);
    }

    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        Node cur = dummyHead.next;
        while (cur != null){
            res.append(cur + "->");
            cur = cur.next;
        }
        res.append("NULL");
        return res.toString();
    }
}
